package com.algaworks.pedidovenda.repository; import java.io.Serializable; import java.math.BigDecimal; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.inject.Inject; import javax.persistence.EntityManager; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.transform.Transformers; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; import com.algaworks.pedidovenda.model.Pedido; import com.algaworks.pedidovenda.model.Usuario; import com.algaworks.pedidovenda.model.vo.DataValor; import com.algaworks.pedidovenda.repository.filter.PedidoFilter; public class Pedidos implements Serializable { private static final long serialVersionUID = 1L; @Inject private EntityManager manager; @SuppressWarnings({ "unchecked" }) public Map<Date, BigDecimal> valoresTotaisPorData(Integer numeroDeDias, Usuario criadoPor) { Session session = manager.unwrap(Session.class); numeroDeDias -= 1; Calendar dataInicial = Calendar.getInstance(); dataInicial = DateUtils.truncate(dataInicial, Calendar.DAY_OF_MONTH); dataInicial.add(Calendar.DAY_OF_MONTH, numeroDeDias * -1); Map<Date, BigDecimal> resultado = criarMapaVazio(numeroDeDias, dataInicial); Criteria criteria = session.createCriteria(Pedido.class); // select date(data_criacao) as data, sum(valor_total) as valor // from pedido where data_criacao >= :dataInicial and vendedor_id = :criadoPor // group by date(data_criacao) criteria.setProjection(Projections.projectionList() .add(Projections.sqlGroupProjection("date(data_criacao) as data", "date(data_criacao)", new String[] { "data" }, new Type[] { StandardBasicTypes.DATE } )) .add(Projections.sum("valorTotal").as("valor")) ) .add(Restrictions.ge("dataCriacao", dataInicial.getTime())); if (criadoPor != null) { criteria.add(Restrictions.eq("vendedor", criadoPor)); } List<DataValor> valoresPorData = criteria .setResultTransformer(Transformers.aliasToBean(DataValor.class)).list(); for (DataValor dataValor : valoresPorData) { resultado.put(dataValor.getData(), dataValor.getValor()); } return resultado; } private Map<Date, BigDecimal> criarMapaVazio(Integer numeroDeDias, Calendar dataInicial) { dataInicial = (Calendar) dataInicial.clone(); Map<Date, BigDecimal> mapaInicial = new TreeMap<>(); for (int i = 0; i <= numeroDeDias; i++) { mapaInicial.put(dataInicial.getTime(), BigDecimal.ZERO); dataInicial.add(Calendar.DAY_OF_MONTH, 1); } return mapaInicial; } @SuppressWarnings("unchecked") public List<Pedido> filtrados(PedidoFilter filtro) { Session session = this.manager.unwrap(Session.class); Criteria criteria = session.createCriteria(Pedido.class) // fazemos uma associação (join) com cliente e nomeamos como "c" .createAlias("cliente", "c") // fazemos uma associação (join) com vendedor e nomeamos como "v" .createAlias("vendedor", "v"); if (filtro.getNumeroDe() != null) { // id deve ser maior ou igual (ge = greater or equals) a filtro.numeroDe criteria.add(Restrictions.ge("id", filtro.getNumeroDe())); } if (filtro.getNumeroAte() != null) { // id deve ser menor ou igual (le = lower or equal) a filtro.numeroDe criteria.add(Restrictions.le("id", filtro.getNumeroAte())); } if (filtro.getDataCriacaoDe() != null) { criteria.add(Restrictions.ge("dataCriacao", filtro.getDataCriacaoDe())); } if (filtro.getDataCriacaoAte() != null) { criteria.add(Restrictions.le("dataCriacao", filtro.getDataCriacaoAte())); } if (StringUtils.isNotBlank(filtro.getNomeCliente())) { // acessamos o nome do cliente associado ao pedido pelo alias "c", criado anteriormente criteria.add(Restrictions.ilike("c.nome", filtro.getNomeCliente(), MatchMode.ANYWHERE)); } if (StringUtils.isNotBlank(filtro.getNomeVendedor())) { // acessamos o nome do vendedor associado ao pedido pelo alias "v", criado anteriormente criteria.add(Restrictions.ilike("v.nome", filtro.getNomeVendedor(), MatchMode.ANYWHERE)); } if (filtro.getStatuses() != null && filtro.getStatuses().length > 0) { // adicionamos uma restrição "in", passando um array de constantes da enum StatusPedido criteria.add(Restrictions.in("status", filtro.getStatuses())); } return criteria.addOrder(Order.asc("id")).list(); } public Pedido guardar(Pedido pedido) { return this.manager.merge(pedido); } public Pedido porId(Long id) { return this.manager.find(Pedido.class, id); } }